package com.cn.wanxi.service.impl;

import com.cn.wanxi.common.ParseTool;
import com.cn.wanxi.common.RedisNumTool;
import com.cn.wanxi.common.ThreadTool;
import com.cn.wanxi.entity.ProductTypeEntity;
import com.cn.wanxi.entity.ResultEntity;
import com.cn.wanxi.mapper.ProductTypeMapper;
import com.cn.wanxi.service.IProductTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

import java.util.ArrayList;
import java.util.List;

@Service
public class ProductTypeServiceImpl implements IProductTypeService {
    @Autowired
    private ProductTypeMapper productTypeMapper;

    @Override
    public ResultEntity add(ProductTypeEntity productTypeEntity) {
        int result = productTypeMapper.add(productTypeEntity);
        resetCache(result, 0);
        return ResultEntity.success(result);
    }

    @Override
    public ResultEntity update(ProductTypeEntity productTypeEntity) {
        int result = productTypeMapper.update(productTypeEntity);
        resetCache(result, productTypeEntity.getId());
        return ResultEntity.success(result);
    }

    @Override
    public ResultEntity delete(ProductTypeEntity productTypeEntity) {
        int result = productTypeMapper.delete(productTypeEntity);
        resetCache(result, productTypeEntity.getId());
        return ResultEntity.success(result);
    }

    @Override
    public List<ProductTypeEntity> findAll(ProductTypeEntity productTypeEntity) {
        final List<ProductTypeEntity>[] list = new List[]{new ArrayList<>()};
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                list[0] = findAllCache(productTypeEntity);
            }
        });
        thread.start();
        ThreadTool.ThreadSleep(thread);
        return list[0];
    }

    @Override
    public ResultEntity<ProductTypeEntity> findById(ProductTypeEntity productTypeEntity) {
        final ProductTypeEntity[] model = {new ProductTypeEntity()};
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                model[0] = findByIdCache(productTypeEntity);
            }
        });
        thread.start();
        ThreadTool.ThreadSleep(thread);
        return ResultEntity.success(model[0]);
    }

    @Override
    public Integer getCount(ProductTypeEntity productTypeEntity) {
        final int[] result = {-1};
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                result[0] = findCountCache(productTypeEntity);
            }
        });
        thread.start();
        ThreadTool.ThreadSleep(thread);
        return result[0];
    }


    /**
     * 查找所有产品种类缓存
     * @param productTypeModel
     * @return
     */
    private List<ProductTypeEntity> findAllCache(ProductTypeEntity productTypeModel) {
        List<ProductTypeEntity> list = new ArrayList<>();
        Jedis jedis = new Jedis();
        jedis.select(RedisNumTool.REDIS_TYPE_PRODUCT);
        boolean cache = jedis.exists("productTypeModelId") && judgeModel(productTypeModel);
        if (cache) {
            Long length = jedis.llen("productTypeModelId");
            for (int i = 0; i < length; i++) {
                ProductTypeEntity model = new ProductTypeEntity();
                model.setId(ParseTool.StringToInt(jedis.lindex("productTypeModelId", i)));
                model.setContent(jedis.lindex("productTypeModelName", i));
                model.setSort(ParseTool.StringToInt(jedis.lindex("productTypeModelSort", i)));
                model.setEnable(ParseTool.StringToInt(jedis.lindex("productTypeModelEnable", i)));
                list.add(model);
            }
        } else {
            list = productTypeMapper.findAll(productTypeModel);
            if (judgeModel(productTypeModel)) {
                for (ProductTypeEntity model :
                        list) {
                    jedis.rpush("productTypeModelId", String.valueOf(model.getId()));
                    jedis.rpush("productTypeModelName", model.getContent());
                    jedis.rpush("productTypeModelSort", String.valueOf(model.getSort()));
                    jedis.rpush("productTypeModelEnable", String.valueOf(model.getEnable()));
                }
            }
        }
        return list;
    }

    /**
     * 根据产品种类id查找单个产品缓存
     * @param productTypeModel
     * @return
     */
    private ProductTypeEntity findByIdCache(ProductTypeEntity productTypeModel) {
        ProductTypeEntity model = new ProductTypeEntity();
        Jedis jedis = new Jedis();
        jedis.select(RedisNumTool.REDIS_TYPE_PRODUCT);
        String cacheName = "productTypeModel_id_" + productTypeModel.getId();
        boolean cache = jedis.exists(cacheName);
        if (cache) {
            model.setId(ParseTool.StringToInt(jedis.hget(cacheName, "id")));
            model.setContent(jedis.hget(cacheName, "name"));
            model.setSort(ParseTool.StringToInt(jedis.hget(cacheName, "sort")));
            model.setEnable(ParseTool.StringToInt(jedis.hget(cacheName, "enable")));
        } else {
            model = productTypeMapper.findById(productTypeModel);
            jedis.hset(cacheName, "id", String.valueOf(model.getId()));
            jedis.hset(cacheName, "name", model.getContent());
            jedis.hset(cacheName, "sort", String.valueOf(model.getSort()));
            jedis.hset(cacheName, "enable", String.valueOf(model.getEnable()));
        }
        return model;
    }

    /**
     * 查找产品种类总数缓存
     * @param productTypeModel
     * @return
     */
    private int findCountCache(ProductTypeEntity productTypeModel) {
        int result = -1;
        Jedis jedis = new Jedis();
        jedis.select(RedisNumTool.REDIS_TYPE_PRODUCT);
        boolean cache = jedis.exists("productTypeModelCount");
        if (cache) {
            result = ParseTool.StringToInt(jedis.get("productTypeModelCount"));
        } else {
            result = productTypeMapper.getCount(productTypeModel);
            jedis.set("productTypeModelCount", String.valueOf(result));
        }
        return result;
    }

    /**
     * 更新后删除Redis中的缓存
     *
     * @param result
     */
    private void resetCache(int result, int id) {
        if (result > 0) {
            Jedis jedis = new Jedis();
            jedis.select(5);
            jedis.del("productTypeModelId", "productTypeModelName", "productTypeModelSort", "productTypeModelEnable");
            jedis.del("productTypeModelCount");
            jedis.del("productTypeModel_id_" + id);
        }
    }

    /**
     * 判断model内是否有值
     * 没有值返回true
     *
     * @param model
     * @return
     */
    private boolean judgeModel(ProductTypeEntity model) {
        return model.getId() == null &&
                model.getContent() == null &&
                model.getSort() == null &&
                ParseTool.enableToInt(model.getEnable()) == 1 &&
                ParseTool.pageToInt(model.getPage()) == 1 &&
                ParseTool.limitToInt(model.getLimit()) == 10;
    }
}
